﻿using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Pro.Common.IoC;

namespace Pro.IoC.Unity
{
    public class UnityComponentContainerConfigurator : IComponentContainerConfigurator
    {
        private readonly IUnityContainer _unityContainer;

        public IUnityContainer UnityContainer
        {
            get
            {
                return _unityContainer;
            }
        }

        public UnityComponentContainerConfigurator(IUnityContainer unityContainer)
        {
            _unityContainer = unityContainer;
        }

        private static readonly Lazy<IEngine> _componentContainer = new Lazy<IEngine>(() =>
        {
            IUnityContainer unityContainer = new UnityContainer();

            UnityComponentContainerConfigurator unityComponentContainerConfigurator = new UnityComponentContainerConfigurator(unityContainer);
            unityComponentContainerConfigurator.AutoRegister();

            IEngine componentContainer = new UnityComponentContainer(unityContainer);
            return componentContainer;
        });

        public static IEngine GetConfiguredComponentContainer()
        {
            return _componentContainer.Value;
        }

        #region IComponentContainerConfigurator Members

        public void RegisterType<TComponent>()
        {
            _unityContainer.RegisterType<TComponent>();
        }

        public void RegisterType<TComponent>(string componentName)
        {
            _unityContainer.RegisterType<TComponent>(componentName);
        }

        public void RegisterType<TComponentFrom, TComponentTo>() where TComponentTo : TComponentFrom
        {
            _unityContainer.RegisterType<TComponentFrom, TComponentTo>();
        }

        public void RegisterType<TComponentFrom, TComponentTo>(string componentName) where TComponentTo : TComponentFrom
        {
            _unityContainer.RegisterType<TComponentFrom, TComponentTo>(componentName);
        }

        public void RegisterType(Type componentType)
        {
            _unityContainer.RegisterType(componentType);
        }

        public void RegisterType(Type componentType, string componentName)
        {
            _unityContainer.RegisterType(componentType, componentName);
        }

        public void RegisterType(Type componentFrom, Type componentTo)
        {
            _unityContainer.RegisterType(componentFrom, componentTo);
        }

        public void RegisterType(Type componentFrom, Type componentTo, string componentName)
        {
            _unityContainer.RegisterType(componentFrom, componentTo, componentName);
        }

        public void RegisterInstance<TComponent>(TComponent componentInstance)
        {
            _unityContainer.RegisterInstance(componentInstance);
        }

        public void RegisterInstance<TComponent>(TComponent componentInstance, string componentInstanceName)
        {
            _unityContainer.RegisterInstance(componentInstanceName, componentInstance);
        }

        #endregion
    }
}
